<template>
  <page-container :title="route.meta.title">
    <SearchTable ref="tableRef" :table-list-api="tableListApi" :columns="columns">
      <template #tableBtns>
        <a-button v-action:create type="primary" @click="handleCreating">新建</a-button>
      </template>
    </SearchTable>
    <DialogViewer v-if="pageType === PAGE_TYPE.VIEW" :form-data="formData" :items="columns" @cancel="handleCancel" />

    <a-modal :open="modalVisible" :width="680" :title="modalTitle" @ok="handleOk" @cancel="handleCancel">
      <a-form ref="formRef" :model="formData" :label-col="{ span: 6, offset: 0 }">
        <a-form-item
          v-for="item of computedItems"
          :key="item.dataIndex"
          :name="item.dataIndex"
          :label="item.title"
          :required="item.required"
        >
          <a-select
            v-if="item.type === 'enum'"
            v-model:value="formData[item.dataIndex]"
            allow-clear
            :options="item.options"
          />
          <a-input v-else v-model:value="formData[item.dataIndex]" />
        </a-form-item>
        <a-form-item name="privilege" label="菜单权限">
          <a-tree-select
            v-model:value="formData.privilege"
            style="width: 100%"
            tree-checkable
            tree-default-expand-all
            :show-checked-strategy="TreeSelect.SHOW_PARENT"
            :tree-data="treeData"
            :max-tag-count="10"
          >
            <template #title="{ label }">{{ label }}</template>
          </a-tree-select>
        </a-form-item>
      </a-form>
    </a-modal>
  </page-container>
</template>

<script setup lang="tsx">
import { useRoute } from 'vue-router';
import AButton from 'ant-design-vue/es/button';
import SearchTable from '@/components/SearchTable';
import useTablePage, { PAGE_TYPE } from '@/hooks/useTablePage';
import { Modal, TreeSelect, type FormInstance, type TreeSelectProps } from 'ant-design-vue';
import { createUser, deleteUser, modifyUser, enableUser } from '@/api/user';
import type { IColumn, IOption, IPrivilege, IRow } from '@/types';
import { getPrivilegeList } from '@/api/login';
import request from '@/utils/request';
import { strToJson } from '@/utils/util';

interface IFormState {
  privilege: string[];
  [k: string]: any;
}

const route = useRoute();
const { pageType } = useTablePage();
const tableRef = ref();
const tableListApi = '/v1/user/list';
const mediaOptions = ref<IOption[]>([]);
const modalTitle = computed(() => (pageType.value === PAGE_TYPE.CREATING ? '新建' : '修改'));
const modalVisible = computed(() => pageType.value === PAGE_TYPE.CREATING || pageType.value === PAGE_TYPE.EDITING);
const columns = computed<IColumn[]>(() => [
  {
    title: '账号名称',
    dataIndex: 'name',
    searchable: true,
    required: true,
  },
  {
    title: '账号邮箱',
    dataIndex: 'email',
    required: true,
    searchable: true,
  },
  {
    title: '角色', // 下拉选择 manager 和media
    dataIndex: 'role',
    required: true,
    options: [
      { label: '管理方', value: 'manager' },
      { label: '媒体方', value: 'media' },
    ],
    type: 'enum',
  },
  {
    title: '媒体名称',
    dataIndex: 'media_id',
    type: 'enum',
    options: mediaOptions.value,
    customRender: ({ record }) => {
      const found = mediaOptions.value.find(option => option.value === record.media_id);
      return found?.label || '';
    },
  },
  {
    title: '菜单权限',
    dataIndex: 'privilege',
  },
  {
    title: '状态',
    type: 'boolean',
    dataIndex: 'status',
    switchLabels: ['启用', '禁用'],
    readonly: true,
    customRender({ text, record }) {
      return (
        <a-switch
          checked={text}
          checkedChildren="启用"
          unCheckedChildren="禁用"
          onClick={(enable: boolean) => handleEnable(record.id, enable)}
        />
      );
    },
  },
  {
    title: '操作',
    dataIndex: 'action',
    align: 'center',
    width: 200,
    fixed: 'right',
    customRender: ({ record }) => {
      // TODO: 按钮需要配置权限
      const btns = [
        <a-button type="link" onClick={() => handleGeting(record)}>
          查看
        </a-button>,
        <a-button type="link" onClick={() => handleEditing(record)}>
          编辑
        </a-button>,
        <a-button type="link" danger onClick={() => handleDeleting(record)}>
          删除
        </a-button>,
      ];

      return btns;
    },
  },
]);

const computedItems = computed(() => {
  return columns.value.filter(item => {
    const exclude = ['action', 'privilege'];
    if (formData.value.role !== 'media') {
      exclude.push('media_id'); // 如果不是媒体方角色，排除'media_id'
    }
    return !exclude.includes(item.dataIndex) && !item.readonly;
  });
});

const treeData = ref<TreeSelectProps['treeData']>([]);
const setPrivilegeList = () => {
  const data: TreeSelectProps['treeData'] = [];
  getPrivilegeList().then(res => {
    const privilege = strToJson<IPrivilege>(res.data.privilege);

    if (!privilege) return;

    Object.keys(privilege).forEach(title => {
      const parent = {
        label: title,
        value: title,
        children: privilege[title].map(item => ({ label: item, value: item })),
      };
      data.push(parent);
    });

    treeData.value = data;
  });
};
setPrivilegeList();

const formData = ref<IFormState>({
  privilege: [],
});

const handleGeting = (record: IRow) => {
  // @ts-ignore
  formData.value = record;
  pageType.value = PAGE_TYPE.VIEW;
};
const setMediaOptions = async () => {
  const data = await request.get('/v1/media/list', { params: { page: 1, page_size: 100 } });
  // @ts-ignore
  mediaOptions.value = data.data.list.map(({ id, name }) => ({ label: name, value: id }));
};
setMediaOptions();
const handleCreating = () => {
  formData.value = { privilege: [] };
  pageType.value = PAGE_TYPE.CREATING;
};

const formatStateForDisplay = (data: IRow): IFormState => {
  const privilege = strToJson<IPrivilege>(data.privilege as string);
  // @ts-ignore
  if (!privilege) return { ...data };

  const arr: IFormState['privilege'] = [];
  Object.keys(privilege).forEach(title => {
    arr.push(...privilege[title]);
  });

  return {
    ...data,
    privilege: arr,
  };
};
const formatStateForStore = (state: IFormState) => {
  // 找到对应的 media_name
  const foundMedia = mediaOptions.value.find(({ value }) => value === state.media_id);
  const privilegeMap: IPrivilege = {};
  state.privilege.forEach(p => {
    const found = treeData.value?.find(({ value }) => value === p);
    if (found) {
      privilegeMap[p] = found.children?.map(({ value }) => value) || [];
    } else {
      const parentItem = treeData.value?.find(({ children }) => children?.find(({ value }) => value === p));
      if (!parentItem) return;

      if (privilegeMap[parentItem.value]) {
        privilegeMap[parentItem.value].push(p);
      } else {
        privilegeMap[parentItem.value] = [p];
      }
    }
  });
  return {
    ...state,
    privilege: JSON.stringify(privilegeMap),
    media_name: foundMedia?.label,
  };
};

const handleEnable = (id: string, enable: boolean) => {
  Modal.confirm({
    title: '警告',
    content: `确认是否${enable ? '启用' : '禁用'}该用户？`,
    okText: '确认',
    cancelText: '取消',
    onOk() {
      return enableUser(id).then(() => {
        tableRef.value.refreshTable();
      });
    },
  });
};

const handleEditing = (record: IRow) => {
  formData.value = formatStateForDisplay(record);
  pageType.value = PAGE_TYPE.EDITING;
};

const handleDeleting = (record: IRow) => {
  Modal.confirm({
    title: '警告',
    content: `确认删除 ${record.name} 吗?`,
    okText: '确认',
    cancelText: '取消',
    onOk() {
      return deleteUser(record.id).then(() => {
        tableRef.value.refreshTable();
      });
    },
  });
};

const formRef = ref<FormInstance>();
const handleOk = async () => {
  await formRef.value?.validate();
  const state = formatStateForStore(formData.value);
  if (pageType.value === PAGE_TYPE.CREATING) {
    await createUser(state);
  } else {
    await modifyUser(state);
  }
  pageType.value = null;
  tableRef.value.refreshTable();
};

const handleCancel = () => {
  pageType.value = null;
  formRef.value?.resetFields();
};
</script>
